module crc
#(
    parameter dat_width = 16,
    parameter crc_width = 6
)
(
    input  [dat_width - 1 : 0] din,
    input  [crc_width - 1 : 0] cin,
    output [crc_width - 2 : 0] dout
);

    //CRC校验生成函数
    function [crc_width - 2 : 0] crc_alu;
        input [dat_width - 1 : 0] data;
        input [crc_width - 1 : 0] crc;

        integer i;
        reg [dat_width - 1 : 0] dreg;
        reg [dat_width - 1 : 0] cunt;

        begin
            dreg = data; cunt = 'b0;
            for(i = 0; i < (2 * dat_width - 1); i = i + 1) begin
                if (dreg[dat_width - 1]) begin
                    dreg = {dreg[dat_width - 1 : dat_width - crc_width] ^ crc, dreg[dat_width - crc_width - 1 : 0]};
                end
                else begin
                    dreg = {dreg[dat_width - 2 : 0], 1'b0};
                    cunt = cunt + 1'b1;
                end
                if (cunt == (dat_width - crc_width)) crc_alu = dreg[dat_width - 2 : dat_width - crc_width];
            end
        end
    endfunction

    assign dout = crc_alu(din, cin);

endmodule 